import React, { Component } from 'react';
import { StyleSheet, Text, ActivityIndicator, View, FlatList, RefreshControl, TouchableOpacity, DeviceEventEmitter } from 'react-native';
import { connect } from 'react-redux';
import actions from '../action/index';
import { createAppContainer } from 'react-navigation';
import { createMaterialTopTabNavigator } from 'react-navigation-tabs';
import PopularItem from '../common/PopularItem';
import Toast from 'react-native-easy-toast';
import NavigationBar from '../common/NavigationBar';
import TrendingDialog, { TimeSpans } from '../common/TrendingDialog';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons'

const EVENT_TYPE_TIME_SPAN_CHANGE = 'EVENT_TYPE_TIME_SPAN_CHANGE';
const URL = 'https://github.com/trending/';
const THEME_COLOR = '#678';

export default class TrendingPage extends Component {
    constructor(props) {
        super(props);
        this.tabNames = ['All', 'C', 'C#', 'PHP', 'JavaScript'];
        this.state = {
            timeSpan: TimeSpans[0],
        }
    }

    _genTabs() {
        const tabs = {};
        this.tabNames.forEach((item, index) => {
            tabs[`tab${index}`] = {
                screen: props => <TrendingTabPage {...props} timeSpan={this.state.timeSpan} tabLabel={item} />,
                navigationOptions: {
                    title: item,
                }
            };
        });
        return tabs;
    }

    renderTitleView() {
        return <View>
            <TouchableOpacity
                underlayColor='transparent'
                onPress={() => this.dialog.show()}>
                <View style={{ flexDirection: 'row', alignItems: 'center' }}>
                    <Text style={{
                        fontSize: 16,
                        color: '#FFFFFF',
                        fontWeight: '400'
                    }}>趋势 {this.state.timeSpan.showText}</Text>
                    <MaterialIcons
                        name={'arrow-drop-down'}
                        size={22}
                        style={{ color: 'white' }}
                    />
                </View>
            </TouchableOpacity>
        </View>
    }

    onSelectTimeSpan(tab) {
        this.dialog.dismiss();
        this.setState({
            timeSpan: tab
        })
        // 发送事件通知导航器里的数据刷新
        DeviceEventEmitter.emit(EVENT_TYPE_TIME_SPAN_CHANGE, tab);
    }

    renderTrendingDialog() {
        return <TrendingDialog
            ref={dialog => this.dialog = dialog}
            onSelect={tab => this.onSelectTimeSpan(tab)}
        />
    }

    _tabNav() {
        if (!this.tabNav) {
            this.tabNav = createAppContainer(createMaterialTopTabNavigator(
                this._genTabs(),
                {
                    tabBarOptions: {
                        tabStyle: styles.tabStyle, // 每个单元格的样式
                        upperCaseLabel: false, // 是否转换大写
                        scrollEnabled: true, // 是否允许滑动
                        style: {
                            backgroundColor: '#a67' // 背景颜色
                        },
                        indicatorStyle: styles.indicatorStyle, // 指示器样式
                        labelStyle: styles.labelStyle
                    }
                }
            ));
        }
        return this.tabNav;
    }

    render() {
        let statusBar = {
            backgroundColor: THEME_COLOR,
            barStyle: 'light-content',
        }
        let navigationBar = <NavigationBar
            titleView={this.renderTitleView()}
            title={'趋势'}
            statusBar={statusBar}
            style={{ backgroundColor: THEME_COLOR }}
        />;
        // 优化，防止每次state变化时都重新渲染一次导航器
        const TabNavigator = this._tabNav();
        return (
            <View style={styles.container}>
                {navigationBar}
                <TabNavigator />
                {this.renderTrendingDialog()}
            </View>
        );
    }
}

const pageSize = 10; // 设置常量，防止修改
class TrendingTab extends Component {
    constructor(props) {
        super(props);
        const { tabLabel, timeSpan } = this.props;
        this.storeName = tabLabel;
        this.timeSpan = timeSpan;
    }

    // 获取与当前页面有关的数据
    _store() {
        const { trending } = this.props;
        let store = trending[this.storeName];
        if (!store) {
            store = {
                items: [],
                isLoading: false,
                projectModel: [], // 要展示的数据
                hideLoadingMore: true, // 默认隐藏加载更多
            }
        }
        return store;
    }

    componentDidMount() {
        this.loadData();
        // 接收事件，注册监听器
        this.timeSpanChangeListener = DeviceEventEmitter.addListener(EVENT_TYPE_TIME_SPAN_CHANGE, (timeSpan) => {
            this.timeSpan = timeSpan;
            this.loadData();
        })
    }

    componentWillUnmount() {
        if (this.timeSpanChangeListener) {
            // 卸载时注销监听器
            this.timeSpanChangeListener.remove();
        }
    }

    loadData(loadMore) {
        const { onLoadTrendingData, onLoadMoreTrending } = this.props;
        const store = this._store();
        const url = this.genFetchUrl(this.storeName);
        if (loadMore) {
            onLoadMoreTrending(this.storeName, ++store.pageIndex, pageSize, url, store.items, callback => {
                this.refs.toast.show('没有更多了');
            });
        } else {
            onLoadTrendingData(this.storeName, url, pageSize);
        }
    }

    genFetchUrl(key) {
        return URL + key + '?' + this.timeSpan.searchText;
    }

    renderItem(data) {
        const item = data.item;
        return <PopularItem
            item={item}
            onselect={() => { }}
            projectModel={{
                isFavorite: false, // 该模块还没开发完，先让所有收藏标志为false
            }}
        />
    }

getIndicator() {
    return this._store().hideLoadingMore ? null :
        <View style={styles.indicatorContainer}>
            <ActivityIndicator
                style={styles.indicator}
            />
            <Text>正在加载更多</Text>
        </View>
}

render() {
    let store = this._store(); // 动态获取store
    if (!store) {
        store = {
            items: [],
            isLoading: false,
        }
    }
    return (
        <View>
            <FlatList
                data={store.projectModel}
                renderItem={data => this.renderItem(data)}
                keyExtractor={item => "" + item.id}
                refreshControl={
                    <RefreshControl
                        title={'Loading'}
                        titleColor={THEME_COLOR}
                        colors={[THEME_COLOR]}
                        refreshing={store.isLoading}
                        onRefresh={() => this.loadData()}
                        tintColor={THEME_COLOR}
                    />
                }
                ListFooterComponent={() => this.getIndicator()}
                onEndReached={() => {
                    setTimeout(() => {
                        if (this.canLoadMore) {
                            this.loadData(true);
                            this.canLoadMore = false;
                        }
                    }, 100);
                }}
                onEndReachedThreshold={0.5}
                onMomentumScrollBegin={() => { // 初始化滚动，解决频繁调用onEndReached的问题
                    this.canLoadMore = true;
                }}
            />
            <Toast ref={'toast'}
                position={'center'}
            />
        </View>
    )
}
}

const mapStateToProps = state => ({
    trending: state.trending
});
const mapDispatchToProps = dispatch => ({
    onLoadTrendingData: (storeName, url, pageSize) => dispatch(actions.onLoadTrendingData(storeName, url, pageSize)),
    onLoadMoreTrending: (storeName, url, pageSize, items, callback) => dispatch(actions.onLoadMoreTrending(storeName, url, pageSize, items, callback))
});
const TrendingTabPage = connect(mapStateToProps, mapDispatchToProps)(TrendingTab);

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10
    },
    tabStyle: {
        minWidth: 50
    },
    indicatorStyle: {
        height: 2,
        backgroundColor: 'white'
    },
    labelStyle: {
        fontSize: 13,
        marginTop: 6,
        marginBottom: 6
    },
    indicatorContainer: {
        alignItems: 'center'
    },
    indicator: {
        color: 'red',
        margin: 10,
    },
})